;
(function() {
	function can_goods_be_bina() {
		return this.getPerm().can_goods_be_bina;
	};
	var skill = {
		canBina: can_goods_be_bina,
		//商家分销商品的数量
		canBinaGoodsNum: function(num) {
			if (num) {
				this.setPerm("data_goods_bina_num", num);
			}
			return this.getPerm().data_goods_bina_num || 1;
		}.perm(can_goods_be_bina, "权限不足，商家未开启商品分销功能"),
		_getBinaGoodsList: function() {
			return this.getPerm().data_goods_bina_list || []
		},
		//永久分销人员列表
		_getForeverBinaUserList: function() {
			return this.getPerm().data_forever_bina_user_list || [];
		},
		addUserToForeverBinaUserList: function(user_id) {
			var user_list = this._getForeverBinaUserList();
			if (user_list.indexOf(user_id) !== -1) {
				throwCusError("用户已经在永久分销人员列表中，无需重复添加")
			}
			if (!UserCon.has(user_id)) {
				throwCusError("找不到指定用户")
			}
			user_list.push(user_id);
			this.setPerm("data_forever_bina_user_list", user_list);

			//把现有的分销商品权限全部提供给这个用户
			var self = this;
			this._getBinaGoodsList().forEach(function(bina_id) {
				self.addUserToBina(bina_id, user_id, null, "silence")
			});
			return this;
		},
		removeUserFromForeverBinaUserList: function(user_id) {
			var user_list = this._getForeverBinaUserList();
			if (user_list.indexOf(user_id) === -1) {
				throwCusError("用户不在永久分销人员列表中");
			}
			user_list = $Array.remove(user_list, user_id);
			this.setPerm("data_forever_bina_user_list", user_list);
			return this;
		},
		//高级分销人员列表
		_getSeniorBinaUserList: function() {
			return this.getPerm().data_senior_bina_user_list || [];
		},
		addUserToSeniorBinaUserList: function(user_id) {
			var user_list = this._getSeniorBinaUserList();
			if (user_list.indexOf(user_id) !== -1) {
				throwCusError("用户已经在高级分销人员列表中，无需重复添加")
			}
			if (!UserCon.has(user_id)) {
				throwCusError("找不到指定用户")
			}
			user_list.push(user_id);
			this.setPerm("data_senior_bina_user_list", user_list);

			return this;
		},
		removeUserFromSeniorBinaUserList: function(user_id) {
			var user_list = this._getSeniorBinaUserList();
			if (user_list.indexOf(user_id) === -1) {
				throwCusError("用户不在高级分销人员列表中");
			}
			user_list = $Array.remove(user_list, user_id);
			this.setPerm("data_senior_bina_user_list", user_list);
			return this;
		},
		tryAddUserToForeverBinaUserListByCumulativeCash: function(user_id) {
			//商家有设置配置，而且用户还不是永久分销人员，尝试性添加成永久分销人员
			if (this.info.data_to_forever_bina_cash && this._getForeverBinaUserList().indexOf(user_id) === -1) {
				var cum_cash = 0;
				this.getBinaListByUserId(user_id).forEach(function(item) {
					var bina = item.bina;
					(bina.getUser(user_id).achs || []).forEach(function(ach_info) {
						cum_cash += ach_info.bina_cash;
					});
				});
				console.log("tryAddUserToForeverBinaUserListByCumulativeCash:", cum_cash);
				if (cum_cash >= this.info.data_to_forever_bina_cash) {
					this.addUserToForeverBinaUserList(user_id);
				}
			} else {
				console.log(this.info.data_to_forever_bina_cash ? "用户已经拥有永久分销权限" : "商家没有设置自动开通永久分销权限")
			}
		},
		//代码片段，获取Bina
		_getBina: function(bina_id) {
			var bina = BinaCon.get(bina_id);
			if (!bina) {
				throwCusError("找不到指定商品分销");
			}
			if (bina.bus_id !== this._id) {
				throwCusError("指定商品分销不属于商家");
			}
			return bina;
		},
		//判断指定商品是否是分销商品
		isBinaGoods: function(goods_id) {
			var data_goods_bina_list = this._getBinaGoodsList();
			return !!data_goods_bina_list.filter(function(bina_id) {
				return BinaCon.equalGoods(bina_id, goods_id);
			}).length;
		}.perm(can_goods_be_bina, function() {
			return false
		}),
		//获取被标记为可分销的商品列表
		getBinaGoodsList: function() {
			var data_goods_bina_list = this._getBinaGoodsList();
			data_goods_bina_list = data_goods_bina_list.map(function(bina_id) {
				var bina = BinaCon.get(bina_id);
				var goods = GoodsCon.get(bina.goods_id);
				return (goods && {
					goods: goods,
					bina: bina,
					goods_custom_bina_buff: goods.use_custom_bina_id && BuffCon.get(goods.use_custom_bina_id)
				});
			});
			var result = $Array.clearNull(data_goods_bina_list);
			if (result.length != data_goods_bina_list.length) {
				this.setPerm("data_goods_bina_list", result.map(function(bina_and_goods) {
					return bina_and_goods.bina._id;
				}));
			}
			return result;
		}.perm(can_goods_be_bina, "权限不足，商家未开启商品分销功能"),
		//设定指定商品列表为分销
		setBinaGoodsList: function(goods_id_list) {
			var old_bina_list = this._getBinaGoodsList();
			//去重
			goods_id_list = $Array.uniq(goods_id_list);
			var data_goods_bina_list = $Array.clearNull(goods_id_list.map(function(goods_id) {
				return BinaCon.build(goods_id)._id
			}));
			//对比新旧列表，改变新旧商品的属性
			var _id_map = {};
			old_bina_list.forEach(function(bina_id) {
				_id_map[bina_id] = 1;
			});
			data_goods_bina_list.forEach(function(bina_id) {
				_id_map[bina_id] = ~~_id_map[bina_id] - 1;
				//重复的就成了0，新的就成了-1，旧的就成为1
			});
			var bina_buff_id = this.getBinaBuff()._id;
			Object.keys(_id_map).forEach(function(bina_id) {
				var value = _id_map[bina_id];
				if (value === 1) { //旧的
					var goods = GoodsCon.getAlone(BinaCon.getGoodsId(bina_id));
					console.log("删除BUFF", bina_buff_id);
					goods._removeBuff(bina_buff_id); //删除buff
					goods.is_bina = false;
				} else if (value === -1) {
					var goods = GoodsCon.getAlone(BinaCon.getGoodsId(bina_id));
					goods._addBuff(bina_buff_id); //添加buff
					goods.is_bina = true;
				}
			});
			return this.setPerm("data_goods_bina_list", data_goods_bina_list);
		}.perm(can_goods_be_bina, "权限不足，商家未开启商品分销功能"),
		//代码片段，格式化分销比例
		_formatBinaBuffConfig: function(bina_buff_info, no_senior) {
			var res_config = {};
			var first = parseFloat(bina_buff_info.first) || 0;
			if (first > 1 || first < 0) {
				throwCusError("错误的折扣范围")
			}
			var second = parseFloat(bina_buff_info.second) || 0;
			if (second > 1 || second < 0) {
				throwCusError("错误的折扣范围")
			}
			res_config.first = first;
			res_config.second = second;

			//三级分销
			if (this.getPerm().can_bina_to_third) {
				var third = parseFloat(bina_buff_info.third) || 0;
				if (third > 1 || third < 0) {
					throwCusError("错误的折扣范围")
				}
				res_config.third = third;
			} else {
				res_config.third = 0;
			}
			if (!no_senior) {
				//高级分销规则，累积开通金额
				var to_senior_bina_cash = parseFloat(bina_buff_info.to_senior_bina_cash) || 0;
				if (to_senior_bina_cash < 0) {
					throwCusError("高级分销规则所需累积消费金额有误")
				}
				res_config.to_senior_bina_cash = to_senior_bina_cash;

				//高级分销规则，配置
				if (typeof bina_buff_info.senior === "object") {
					res_config.senior = this._formatBinaBuffConfig(bina_buff_info.senior, true)
				}
			}
			return res_config;
		},
		setBinaBuff: function(bina_config) {
			var bina_buff_info = this._formatBinaBuffConfig(bina_config);
			var data_bina_buff = this.getBinaBuff();
			data_bina_buff.setConfig(bina_buff_info);
			return data_bina_buff;
		}.perm(can_goods_be_bina, "权限不足，商家未开启商品分销功能"),
		getBinaBuff: function() {
			var data_bina_buff_id = this.getPerm().data_bina_buff_id;
			console.log("data_bina_buff_id:", data_bina_buff_id);
			if (!data_bina_buff_id) {
				var data_bina_buff = new BuffCon({
					name: "商品分销",
					code_id: "商品分销",
					config: {
						first: 0.2,
						second: 0.1,
						third: 0
					}
				});
				this.setPerm("data_bina_buff_id", data_bina_buff._id);
			} else {
				data_bina_buff = BuffCon.get(data_bina_buff_id);
			}
			return data_bina_buff;
		}.perm(can_goods_be_bina, "权限不足，商家未开启商品分销功能"),
		//获取拥有分销权限的所有用户ID
		_getBinaUserIdList: function() {
			var data_goods_bina_list = this._getBinaGoodsList();
			var user_list = [];
			data_goods_bina_list.forEach(function(bina_id) {
				var bina = BinaCon.get(bina_id);
				user_list = user_list.concat(bina.getUserIdList());
			});
			user_list = $Array.uniq(user_list);
			return user_list;
		},
		//赋予用户某个商品的分销权限
		addUserToBina: function(bina_id, user_id, recommender_id, is_silence) {
			if (!UserCon.has(user_id)) {
				throwCusError("找不到指定用户");
			}
			if (recommender_id && !UserCon.has(recommender_id)) {
				throwCusError("找不到指定推荐者");
			}
			var bina = this._getBina(bina_id);
			bina._addUser(user_id, recommender_id, is_silence);
		},
		//冻结用户对某个商品的的分销权限，不能移除，不然关系链就断开了
		lockUserFromBina: function(bina_id, user_id) {
			var bina = this._getBina(bina_id);
			bina._lockUser(user_id);
			return bina;
		},
		unlockUserFromBina: function(bina_id, user_id) {
			var bina = this._getBina(bina_id);
			bina._unlockUser(user_id);
			return bina;
		},
		//获取某用户分销的商品列表
		getBinaListByUserId: function(user_id) {
			var data_goods_bina_list = this._getBinaGoodsList();
			var bina_list = [];
			data_goods_bina_list.forEach(function(bina_id) {
				var bina = BinaCon.get(bina_id);
				if (bina.hasBuyed(user_id)) {
					bina_list.push({
						bina: bina
					});
				}
			});
			return bina_list;
		},
		//获取某分销商品的用户列表
		getUserListByBinaId: function(bina_id) {
			var bina = this._getBina(bina_id);
			var user_list = bina.getUserIdList().map(function(user_id) {
				return {
					user: UserCon.get(user_id)
				};
			});
			return user_list;
		},
		// 获取分销关系网中的用户详情
		getUserMapByBinaId: function(bina_id) {
			var bina = this._getBina(bina_id);
			var user_map = Object.assign({}, bina._getUserMap());
			for (var user_id in user_map) {
				user_map[user_id].user = UserCon.get(user_id)
			}
			return user_map;
		},
		//获取拥有分销权限的所有用户以及对应的分销信息
		getBinaUser: function() {
			var self = this;
			return this._getBinaUserIdList().map(function(user_id) {
				return self.getBinaUserById(user_id);
			});
		},
		//获取某用户的分销信息
		getBinaUserById: function(user_id) {
			var user = UserCon.get(user_id);
			var bus_bina = user._getBinaBus(this._id)[0];
			delete bus_bina.bus_id;
			bus_bina.user_id = user_id;
			bus_bina.user = user;
			return bus_bina;
		},
		bina_申请兑换中_to_商家已付款: function(user_id) {
			var user = UserCon.get(user_id);
			var exchange_acc = user._getBinaExchangeAccBuyBusId(this._id);
			if (exchange_acc.state !== BinaCon.STATE.申请兑换中) {
				throwCusError("兑现所在状态无法进行相应转换")
			}
			exchange_acc.state = BinaCon.STATE.商家已付款;
			user._setBinaExchangeAccBuyBusId(this._id, exchange_acc);
		},
		getGoodsBinaBuff: function(goods_id) {
			var goods = this._getGoods(goods_id);
			if (goods.use_custom_bina_id) {
				var data_bina_buff = BuffCon.get(goods.use_custom_bina_id);
				return data_bina_buff;
			}
		},
		setGoodsBinaBuff: function(goods_id, bina_buff_info) {
			bina_buff_info = this._formatBinaBuffConfig(bina_buff_info);
			var goods = this._getGoods(goods_id);
			if (goods.use_custom_bina_id) {
				var data_bina_buff = BuffCon.get(goods.use_custom_bina_id);
			}
			if (!data_bina_buff) {
				data_bina_buff = new BuffCon({
					name: "商品分销",
					code_id: "商品分销",
					config: bina_buff_info
				});
				goods.use_custom_bina_id = data_bina_buff._id;
				goods.save();
			} else {
				data_bina_buff.setConfig(bina_buff_info);
			}
			return {
				goods: goods,
				bina: BinaCon.build(goods._id),
				goods_custom_bina_buff: data_bina_buff
			};
		},
		removeGoodsBinaBuff: function(goods_id) {
			var goods = this._getGoods(goods_id);
			if (goods.use_custom_bina_id) {
				var data_bina_buff = BuffCon.get(goods.use_custom_bina_id);
				if (data_bina_buff) {
					data_bina_buff.destroy();
				}
				goods.use_custom_bina_id = null;
				goods.save();
			}
			return {
				goods: goods,
				bina: BinaCon.build(goods._id),
				goods_custom_bina_buff: null
			};
		}
	};

	module.exports = skill;
	var db = require("../db/index");
	var BinaCon = require("../bina/_con");
	var DomainCon = require("../domain/_con");
	var GoodsCon = require("../goods/_con");
	var UserCon = require("../user/_con");
	var BusCon = require("../bus/_con");
	var AchCon = require("../ach/_con");
	var ClassifyCon = require("../bus.classify/_con");
	var TagCon = require("../bus.tag/_con");
	var LeagueCon = require("../league/_con");
	var BuffCon = require("../buff/_con");
	var BusUserBindCon = require("../bus_user_bind/_con");
	var BusGuideCon = require("../bus.guide/_con");
	var CommentCon = require("../comment/_con");
	var config = require("../_include/config");
	var data_cut = require("../_include/data_cut");
	var helper = require("../_include/helper");
	var md5 = require("../_include/md5");
	var $Object = require("../_include/$.Object");
	var $Array = require("../_include/$.Array");
	var tld = require('tldjs');
	var fs = require("fs");
	var Fiber = require('fibers');
}());